﻿/**	@file		archive_supported_UDT.hpp
 *	@date		(2009-01-25 14:04:49)/(2011-10-30 23:53:20)
 *-----------------------------------------------------------------------------
 *	@version	1.0.11.19
 *	@author		Nick Shallery	(nicknide@gmail.com)
 *	@copyright	YOU HAVE ALL LEFT WITH THIS CODE WHILE YOU KEEP COMMENT IN EVERY COPY.
 *-----------------------------------------------------------------------------
**/

#if			!defined(__LOLIX_TOY__ARCHIVE__SUPPORTED_UDT__NICK__K_IN_G__)
#define		__LOLIX_TOY__ARCHIVE__SUPPORTED_UDT__NICK__K_IN_G__
//==============================================================================
//--------------------------------------------------------------------------

#if			!defined(__LOLIX_TOY__ARCHIVE__NICK__K_IN_G__)
	#include	"./archive.hpp"
#endif	//	!defined(__LOLIX_TOY__ARCHIVE__NICK__K_IN_G__)

#if			defined(LOLIX_DEF__ARC_SUPPORT_ALL)
	#if			!defined(LOLIX_DEF__ARC_SUPPORT_BYTE_BUF)
		#define	LOLIX_DEF__ARC_SUPPORT_BYTE_BUF
	#endif	//	!defined(LOLIX_DEF__ARC_SUPPORT_BYTE_BUF)
	#if			!defined(LOLIX_DEF__ARC_SUPPORT_KEY_BIND)
		#define	LOLIX_DEF__ARC_SUPPORT_KEY_BIND
	#endif	//	!defined(LOLIX_DEF__ARC_SUPPORT_KEY_BIND)
	#if			!defined(LOLIX_DEF__ARC_SUPPORT_LIST)
		#define	LOLIX_DEF__ARC_SUPPORT_LIST
	#endif	//	!defined(LOLIX_DEF__ARC_SUPPORT_LIST)
	#if		!defined(LOLIX_DEF__ARC_SUPPORT_MAP)
		#define	LOLIX_DEF__ARC_SUPPORT_MAP
	#endif	//	!defined(LOLIX_DEF__ARC_SUPPORT_MAP)
	#if		!defined(LOLIX_DEF__ARC_SUPPORT_STRING)
		#define	LOLIX_DEF__ARC_SUPPORT_STRING
	#endif	//	!defined(LOLIX_DEF__ARC_SUPPORT_STRING)
	#if		!defined(LOLIX_DEF__ARC_SUPPORT_VEC_MAP)
		#define	LOLIX_DEF__ARC_SUPPORT_VEC_MAP
	#endif	//	!defined(LOLIX_DEF__ARC_SUPPORT_VEC_MAP)
	#if		!defined(LOLIX_DEF__ARC_SUPPORT_VEC_SET)
		#define	LOLIX_DEF__ARC_SUPPORT_VEC_SET
	#endif	//	!defined(LOLIX_DEF__ARC_SUPPORT_VEC_SET)
	#if		!defined(LOLIX_DEF__ARC_SUPPORT_VECTOR)
		#define	LOLIX_DEF__ARC_SUPPORT_VECTOR
	#endif	//	!defined(LOLIX_DEF__ARC_SUPPORT_VECTOR)
#endif	//	defined(LOLIX_DEF__ARC_SUPPORT_ALL)

namespace lolix{namespace toy{

	template<typename _Teh, typename _TDat>
	LOLIX_INLINE_CALL archive<_Teh>& operator << (archive<_Teh>& arc, const _TDat& val);
	template<typename _Teh, typename _TDat>
	LOLIX_INLINE_CALL archive<_Teh>& operator >> (archive<_Teh>& arc, _TDat& val);
}}



#define		LOLIX_DEFINE__SUPPORT_ARCHIVE_BLOCK(type)	\
	template<typename _Teh>	LOLIX_INLINE_CALL\
	::lolix::toy::archive<_Teh>& operator >> (::lolix::toy::archive<_Teh>& arc, type& val)\
	{\
		return arc.read(&val, sizeof val);\
	}\
	template<typename _Teh>	LOLIX_INLINE_CALL\
	::lolix::toy::archive<_Teh>& operator << (::lolix::toy::archive<_Teh>& arc, const type& val)\
	{\
		return arc.write(&val, sizeof val);\
	}


namespace lolix{namespace toy{
#define	__LOLIX_TMP_DEFINE__ARC_STANDE_TYPE(type)	\
	template<typename _Teh>	LOLIX_INLINE_CALL\
	archive<_Teh>& operator << (archive<_Teh>& arc, type val){ return arc.write(&val, sizeof val); }\
	template<typename _Teh>	LOLIX_INLINE_CALL\
	archive<_Teh>& operator >> (archive<_Teh>& arc, type& val){ return arc.read(&val, sizeof val); }

	__LOLIX_TMP_DEFINE__ARC_STANDE_TYPE(lx_u8);
	__LOLIX_TMP_DEFINE__ARC_STANDE_TYPE(lx_u16);

	__LOLIX_TMP_DEFINE__ARC_STANDE_TYPE(lx_i8);
	__LOLIX_TMP_DEFINE__ARC_STANDE_TYPE(lx_i16);

	__LOLIX_TMP_DEFINE__ARC_STANDE_TYPE(lx_f32);
	__LOLIX_TMP_DEFINE__ARC_STANDE_TYPE(lx_f64);

	__LOLIX_TMP_DEFINE__ARC_STANDE_TYPE(lx_char);
	__LOLIX_TMP_DEFINE__ARC_STANDE_TYPE(lx_wchar);

	__LOLIX_TMP_DEFINE__ARC_STANDE_TYPE(LOLIX_ITF_ID);

#undef	__LOLIX_TMP_DEFINE__ARC_STANDE_TYPE

	class	size_value
	{
		lx_u64	_val;

		union _T_sv_dat
		{
			struct
			{
				lx_u32	dat_l;
				lx_u32	dat_h;
			};
			lx_u64	dat;

			LOLIX_INLINE_CALL void operator >>= (lx_u32 i)
			{
				//	i during [0, 32)
#if			LOLIX_CFG__SIZE_TYPE_BITS_SIZE <= 32
				dat_l >>= i;
				dat_l |= (dat_h<<(32-i));
				dat_h >>= i;
#else	//	LOLIX_CFG__SIZE_TYPE_BITS_SIZE <= 32
				dat >>= i;
#endif	//	LOLIX_CFG__SIZE_TYPE_BITS_SIZE <= 32
			}

			LOLIX_INLINE_CALL void operator <<= (lx_u32 i)
			{
				//	i during [0, 32)
#if			LOLIX_CFG__SIZE_TYPE_BITS_SIZE <= 32
				if ( i <= 31 )
				{
					dat_h <<= i;
					dat_h |= (dat_l >> (32-i));
					dat_l <<= i;
				}
				else
				{
					dat_h = (dat_l<<(i-32));
					dat_l = 0;
				}

#else	//	LOLIX_CFG__SIZE_TYPE_BITS_SIZE <= 32
				dat <<= i;

#endif	//	LOLIX_CFG__SIZE_TYPE_BITS_SIZE <= 32
			}

			LOLIX_INLINE_CALL lx_u8 get_bits(void)const
			{
				lx_u8 len_size = 0;
#if			LOLIX_CFG__SIZE_TYPE_BITS_SIZE <= 32
				lx_u32 tmp = 0xffffffff;
				for ( lx_u8 i = 0; i != 32 && (dat_l & tmp); ++i, (tmp <<= 1) )
					if ( dat_l | (1<<i) )
						len_size = i;

				tmp = 0xffffffff;
				for ( lx_u8 i = 0; i != 32 && (dat_h & tmp); ++i, (tmp<<=1) )
					if ( dat_h | (1<<i) )
						len_size = 32 + i;

#else	//	LOLIX_CFG__SIZE_TYPE_BITS_SIZE <= 32
				lx_u64 tmp = ~0ull;
				for ( lx_u8 i = 0; i != 64 && (dat & tmp); ++i, (tmp <<= 1) )
					if ( dat | (1ull<<i) )
						len_size = i;

#endif	//	LOLIX_CFG__SIZE_TYPE_BITS_SIZE <= 32
				return len_size + 1;
			}
		};
	public:
		LOLIX_INLINE_CALL	size_value(void){}
		template<typename _Ty>
		LOLIX_INLINE_CALL	explicit size_value(_Ty val):_val(val){}
		template<typename _Ty>
		LOLIX_INLINE_CALL	operator _Ty(void)const
		{
			return (_Ty)_val;
		}

#define	__LOLIX_TMP_DEF__(opt)	LOLIX_INLINE_CALL bool operator opt (size_value const& sv)const{return _val opt sv._val;}
		__LOLIX_TMP_DEF__(==);
		__LOLIX_TMP_DEF__(!=);
		__LOLIX_TMP_DEF__(>);
		__LOLIX_TMP_DEF__(>=);
		__LOLIX_TMP_DEF__(<);
		__LOLIX_TMP_DEF__(<=);
#undef	__LOLIX_TMP_DEF__

		template<typename _Tarc>
		LOLIX_INLINE_CALL void read(_Tarc& arc)
		{
			lx_u8 opval;
			arc >> opval;
			const lx_u8 len_size = (opval & 0x0f);
			_T_sv_dat dat;
			dat.dat_h = 0;
			dat.dat_l = (opval >>= 4);
			for ( lx_u8 i = 0; i != len_size; ++i )
			{
				arc >> opval;
				_T_sv_dat tmp;
				tmp.dat_h = 0;
				tmp.dat_l = opval;
				tmp <<= (i*8 + 4);
				dat.dat_l |= tmp.dat_l;
				dat.dat_h |= tmp.dat_h;
			}

			_val = dat.dat;
		}
		template<typename _Tarc>
		LOLIX_INLINE_CALL void write(_Tarc& arc)const
		{
			_T_sv_dat sv_dat;
			sv_dat.dat = _val;

			lx_u8 len_size = sv_dat.get_bits();

			len_size += 4;
			len_size /= 8;

			lx_u8 ipval = len_size;
			LOLIX_ASSERT(ipval <= 8, L"len_size over flow");
			ipval |= ((sv_dat.dat_l & 0x0f)<<4);
			arc << ipval;
			sv_dat >>= 4;
			for ( lx_u8 i = 0; i != len_size; ++i )
			{
				ipval = (lx_u8)(sv_dat.dat_l&0xff);
				sv_dat >>= 8;
				arc << ipval;
			}
		}
	};
#define	__LOLIX_TMP_DEF__(opt)	\
	template<typename _Ty>LOLIX_INLINE_CALL bool operator opt (_Ty const& l, size_value const& r){return l opt (_Ty)r;}\
	template<typename _Ty>LOLIX_INLINE_CALL bool operator opt (size_value const& l, _Ty const& r){return (_Ty)l opt r;}
	__LOLIX_TMP_DEF__(==);
	__LOLIX_TMP_DEF__(!=);
	__LOLIX_TMP_DEF__(>);
	__LOLIX_TMP_DEF__(>=);
	__LOLIX_TMP_DEF__(<);
	__LOLIX_TMP_DEF__(<=);
#undef	__LOLIX_TMP_DEF__


	template<typename _Tx>
	class _size_value_arc
	{
	public:
		LOLIX_INLINE_CALL	_size_value_arc<_Tx>(void){}
		template<typename _Ty>
		LOLIX_INLINE_CALL	explicit _size_value_arc<_Tx>(_Ty val):_val(val){}
		template<typename _Ty>
		LOLIX_INLINE_CALL	operator _Ty(void)const
		{
			return (_Ty)_val;
		}

		template<typename _Tarc>
		LOLIX_INLINE_CALL void read(_Tarc& arc)
		{
			if ( !arc.is_pack_value() )
			{
				arc.read(&_val, sizeof _val);
				return;
			}

			size_value sv;
			arc >> sv;
			_val = sv;
		}

		template<typename _Tarc>
		LOLIX_INLINE_CALL void write(_Tarc& arc)const
		{
			if ( !arc.is_pack_value() )
			{
				arc.write(&_val, sizeof _val);
				return;
			}

			size_value sv(_val);
			arc << sv;
		}
	private:
		_Tx _val;
	};


#define	__LOLIX_TMP_DEFINE__ARC_STANDE_TYPE(type)	\
	/*LOLIX_DEFINE__SUPPORT_ARCHIVE_READ_WRITE_TEMPLATE(_size_value_arc<type>);*/\
	template<typename _Teh>	LOLIX_INLINE_CALL\
	archive<_Teh>& operator << (archive<_Teh>& arc, type val){ _size_value_arc<type> sv(val); return arc<<sv; }\
	template<typename _Teh>	LOLIX_INLINE_CALL\
	archive<_Teh>& operator >> (archive<_Teh>& arc, type& val){ _size_value_arc<type> sv; arc >> sv; val = (type)sv; return arc; }

	__LOLIX_TMP_DEFINE__ARC_STANDE_TYPE(lx_i32);
	__LOLIX_TMP_DEFINE__ARC_STANDE_TYPE(lx_u32);
	__LOLIX_TMP_DEFINE__ARC_STANDE_TYPE(lx_i64);
	__LOLIX_TMP_DEFINE__ARC_STANDE_TYPE(lx_u64);

	//__LOLIX_TMP_DEFINE__ARC_STANDE_TYPE(wchar_t);

#undef	__LOLIX_TMP_DEFINE__ARC_STANDE_TYPE

#if			defined(LOLIX_DEF__CC_TYPE_MS)
	template<typename _Teh, enum _Tenum>	LOLIX_INLINE_CALL
		archive<_Teh>& operator << (archive<_Teh>& arc, enum _Tenum ve){ lx_u32 val = ve; return arc << val; }
	template<typename _Teh, enum _Tenum>	LOLIX_INLINE_CALL
		archive<_Teh>& operator >> (archive<_Teh>& arc, enum _Tenum& ve){ lx_u32 val; archive<_Teh>& rtv = arc >> val; va = (_Tenum)val; return rtv; }
#endif	//	defined(LOLIX_DEF__CC_TYPE_MS)

	template<typename _Teh, typename _Tv, size_type array_size>	LOLIX_INLINE_CALL
		archive<_Teh>& operator << (archive<_Teh>& arc, _Tv (&val)[array_size])
		{
		for ( size_type i = 0; i != array_size; ++i )
			arc << val[i];
		return arc;
		}
	template<typename _Teh, typename _Tv, size_type array_size>	LOLIX_INLINE_CALL
		archive<_Teh>& operator >> (archive<_Teh>& arc, _Tv (&val)[array_size])
		{
		for ( size_type i = 0; i != array_size; ++i )
			arc >> val[i];
		return arc;
		}
}}

namespace lolix{namespace toy{
	template<typename _Tarc>
	LOLIX_INLINE_CALL _Tarc& handle_archive_return(_Tarc& v, _Tarc&)
	{
		return v;
	}

	template<typename _Tarc>
	LOLIX_INLINE_CALL _Tarc& handle_archive_return(bool v, _Tarc& arc)
	{
		if ( v )
		{
			auto& eh = arc.get_eh();
			eh.handle_write_error(arc.get_fh(), 0, 0, LOLIX_ERROR_INVALID_OPERATOR);
		}

		return arc;
	}

	template<typename _Tarc>
	LOLIX_INLINE_CALL _Tarc& handle_archive_return(LOLIX_RETNV rtv, _Tarc& arc)
	{
		if ( LOLIX_IS_ERROR(rtv) )
		{
			auto& eh = arc.get_eh();
			eh.handle_write_error(arc.get_fh(), 0, 0, rtv);
		}
		return arc;
	}

}}

namespace lolix{namespace toy{namespace _help{

	////////////////////////////////////////////////////////////////////////////////////
	////////////////////////////////////////////////////////////////////////////////////
	template<typename _Tret>
	struct __Check_return_value_help
	{
		template<typename _Tobj, typename _Tarc>
		static LOLIX_INLINE_CALL _Tarc& do_read(_Tobj& obj, _Tarc& arc)
		{
			return handle_archive_return(obj.read(arc), arc);
		}

		template<typename _Tobj, typename _Tarc>
		static LOLIX_INLINE_CALL _Tarc& do_write(_Tobj& obj, _Tarc& arc)
		{
			return handle_archive_return(obj.write(arc), arc);
		}

		template<typename _Tobj>
		static LOLIX_INLINE_CALL _Tret& do_read(_Tobj& obj, _Tret& arc)
		{
			return handle_archive_return(obj.read(arc), arc);
		}

		template<typename _Tobj>
		static LOLIX_INLINE_CALL _Tret& do_write(_Tobj& obj, _Tret& arc)
		{
			return handle_archive_return(obj.write(arc), arc);
		}
	};

	template<>
	struct __Check_return_value_help<void>
	{
		template<typename _Tobj, typename _Tarc>
		static LOLIX_INLINE_CALL _Tarc& do_read(_Tobj& obj, _Tarc& arc)
		{
			obj.read(arc);
			return arc;
		}

		template<typename _Tobj, typename _Tarc>
		static LOLIX_INLINE_CALL _Tarc& do_write(_Tobj& obj, _Tarc& arc)
		{
			obj.write(arc);
			return arc;
		}
	};

	template<typename _Tarc, typename _Tv>
	LOLIX_INLINE_CALL _Tarc& __ArcWrite(_Tarc& arc, _Tv& val, __Check_return_value_help<decltype(val.write(arc))>* crvh = 0)
	{ return crvh->do_write(val, arc);(void)crvh; }

	template<typename _Tarc, typename _Tv>
	LOLIX_INLINE_CALL _Tarc& __ArcRead(_Tarc& arc, _Tv& val, __Check_return_value_help<decltype(val.read(arc))>* crvh = 0)
	{ return crvh->do_read(val, arc);(void)crvh; }
}}}


namespace lolix{namespace toy{

	template<typename _Teh, typename _TDat>
	LOLIX_INLINE_CALL archive<_Teh>& operator << (archive<_Teh>& arc, const _TDat& val)
	{
		return _help::__ArcWrite(arc, val, 0);
	}
	template<typename _Teh, typename _TDat>
	LOLIX_INLINE_CALL archive<_Teh>& operator >> (archive<_Teh>& arc, _TDat& val)
	{
		return _help::__ArcRead(arc, val, 0);
	}
}}


//--------------------------------------------------------------------------
//==============================================================================
#endif	//	!defined(__LOLIX_TOY__ARCHIVE__SUPPORTED_UDT__NICK__K_IN_G__)


#if			defined(LOLIX_DEF__ARC_SUPPORT_BYTE_BUF) && !defined(__LOLIX_DEFIEND__ARC_SUPPORT_BYTE_BUF__)
	#define		__LOLIX_DEFIEND__ARC_SUPPORT_BYTE_BUF__

	#if			!defined(__LOLIX__LOLIX_TYPE__K_IN_G__)
		#include	"../lolix_type.h"
	#endif	//	!defined(__LOLIX__LOLIX_TYPE__K_IN_G__)


namespace lolix{namespace toy{namespace _help{
	template<typename _Teh>
	archive<_Teh>& operator << (archive<_Teh>& arc, byte_buffer bb)
		{
		arc << bb.val;
		}

	template<typename _Teh>
	archive<_Teh>& operator >> (archive<_Teh>& arc, byte_buffer& bb)
		{
		arc >> bb.val;
		}
}}}

#endif	//	defined(LOLIX_DEF__ARC_SUPPORT_BYTE_BUF) && !defined(__LOLIX_DEFIEND__ARC_SUPPORT_BYTE_BUF__)


#if			defined(LOLIX_DEF__ARC_SUPPORT_KEY_BIND) && !defined(__LOLIX_DEFIEND__ARC_SUPPORT_KEY_BIND__)
	#define		__LOLIX_DEFIEND__ARC_SUPPORT_KEY_BIND__

	#if			!defined(__LOLIX__TOY__KEY_BIND__K_IN_G__)
		#include	"./key_bind.hpp"
	#endif	//	!defined(__LOLIX__TOY__KEY_BIND__K_IN_G__)

namespace lolix{namespace toy{namespace _help{
	class key_bind_archive
	{
	public:
	template <typename _KeyBind, typename _Arc>
	LOLIX_INLINE_CALL static _Arc& write(_Arc& arc, _KeyBind const& dat)
		{
		arc << dat.size();
		for ( typename _KeyBind::const_iterator iter = dat.begin(), iter_end = dat.end()
			; iter != iter_end
				; ++iter )
			{
			typename _KeyBind::value_type const& val(*iter);
			arc << val.first
				<< val.second;
			}
		return arc;
		}

	template <typename _KeyBind, typename _Arc>
	LOLIX_INLINE_CALL static _Arc& read(_Arc& arc, _KeyBind& dat)
		{
		typename _KeyBind::size_type dat_size;
		arc >> dat_size;
		_KeyBind new_dat(dat._bind_mode, dat._key_buf.get_allocator());
		auto destroy_new_dat(arc.get_eh().push_destroy(&new_dat));
		for ( size_type i = 0; i != dat_size; ++i )
			{
			typename _KeyBind::key_type key;
			typename _KeyBind::mapped_type val;
			arc >> key >> val;
			typedef key_bind_random<typename _KeyBind::mapped_type, _KeyBind::max_capacity, _KeyBind::row_size, typename _KeyBind::allocator_type>	_Key_random;
			reinterpret_cast<_Key_random&>(new_dat).set_value_by_key((typename _Key_random::key_type&)(key), val);
			}
		dat.swap(new_dat);
		return arc;
		}
	template <typename _Arc, typename _KeyType>
	LOLIX_INLINE_CALL static _Arc& write_key(_Arc& arc, _KeyType k)
		{
		return arc << k._key;
		}
	template <typename _Arc, typename _KeyType>
	LOLIX_INLINE_CALL static _Arc& read_key(_Arc& arc, _KeyType& k)
		{
		return arc >> k._key;
		}
	};
}}}

namespace lolix{namespace toy{
	template<typename _Teh
		, typename _Tbind_type, size_type max_element_size, size_type row_size_input, typename _TAlc, typename need_adjust_free_prev_pointer> LOLIX_INLINE_CALL
		archive<_Teh>& operator << (archive<_Teh>& arc, key_bind<_Tbind_type, max_element_size, row_size_input, _TAlc, need_adjust_free_prev_pointer> const& dat)
		{
		return _help::key_bind_archive::write(arc, dat);
		}

	template<typename _Teh
		, typename _Tbind_type, size_type max_element_size, size_type row_size_input, typename _TAlc, typename need_adjust_free_prev_pointer> LOLIX_INLINE_CALL
		archive<_Teh>& operator >> (archive<_Teh>& arc, key_bind<_Tbind_type, max_element_size, row_size_input, _TAlc, need_adjust_free_prev_pointer>& dat)
		{
		return _help::key_bind_archive::read(arc, dat);
		}

	template<typename _Teh
		, typename _Tbind_type, size_type max_element_size, size_type row_size_input, typename _TAlc> LOLIX_INLINE_CALL
		archive<_Teh>& operator << (archive<_Teh>& arc, key_bind_random<_Tbind_type, max_element_size, row_size_input, _TAlc> const& dat)
		{
		return _help::key_bind_archive::write(arc, reinterpret_cast<const key_bind<_Tbind_type, max_element_size, row_size_input, _TAlc, type_true>&>(dat));
		}

	template<typename _Teh
		, typename _Tbind_type, size_type max_element_size, size_type row_size_input, typename _TAlc> LOLIX_INLINE_CALL
		archive<_Teh>& operator >> (archive<_Teh>& arc, key_bind_random<_Tbind_type, max_element_size, row_size_input, _TAlc>& dat)
		{
		return _help::key_bind_archive::read(arc, reinterpret_cast<key_bind<_Tbind_type, max_element_size, row_size_input, _TAlc, type_true>&>(dat));
		}


	template<typename _Teh, size_type _Max_size, typename _TBind>
	LOLIX_INLINE_CALL archive<_Teh>& operator << (archive<_Teh>& arc, key_type<_Max_size, _TBind> dat)
		{
		return _help::key_bind_archive::write_key(arc, dat);
		}
	template<typename _Teh, size_type _Max_size, typename _TBind>
	LOLIX_INLINE_CALL archive<_Teh>& operator >> (archive<_Teh>& arc, key_type<_Max_size, _TBind>& dat)
		{
		return _help::key_bind_archive::read_key(arc, dat);
		}

}}
#endif	//	defined(LOLIX_DEF__ARC_SUPPORT_KEY_BIND) && !defined(__LOLIX_DEFIEND__ARC_SUPPORT_KEY_BIND__)


#if			defined(LOLIX_DEF__ARC_SUPPORT_LIST) && !defined(__LOLIX_DEFIEND__ARC_SUPPORT_LIST__)
	#define		__LOLIX_DEFIEND__ARC_SUPPORT_LIST__

	#if			!defined(__LOLIX__TOY__STD_LIST__NICK__K_IN_G__)
		#include	"./std_list.hpp"
	#endif	//	!defined(__LOLIX__TOY__STD_LIST__NICK__K_IN_G__)
namespace lolix{namespace toy{
	template<typename _Teh, typename _Ty, typename _Talc> LOLIX_INLINE_CALL
	archive<_Teh>&	operator << (archive<_Teh>& arc, list<_Ty, _Talc> const& vec)
		{
		size_value sv(vec.size());
		arc << sv;
		for ( typename list<_Ty, _Talc>::const_iterator iter = vec.begin(), iter_end = vec.end()
			; iter != iter_end
				; ++iter )
			arc << *iter;
		return arc;
		}

	template<typename _Teh, typename _Ty, typename _Talc> LOLIX_INLINE_CALL
	archive<_Teh>&	operator >> (archive<_Teh>& arc, list<_Ty, _Talc>& vec)
		{
		size_value sv;
		arc >> sv;
		vec.clear();
		for ( size_type i = 0; i != (size_type)sv; ++i )
			{
			_Ty tmp;
			auto destroy_tmp(arc.get_eh().push_destroy(&tmp));
			arc >> tmp;
			vec.push_back(tmp);
			}
		return arc;
		}
}}
#endif	//	defined(LOLIX_DEF__ARC_SUPPORT_LIST) && !defined(__LOLIX_DEFIEND__ARC_SUPPORT_LIST__)

#if			defined(LOLIX_DEF__ARC_SUPPORT_MAP) && !defined(__LOLIX_DEFIEND__ARC_SUPPORT_MAP__)
	#define		__LOLIX_DEFIEND__ARC_SUPPORT_MAP__
	#if			!defined(__LOLIX__TOY__STD_MAP__NICK__K_IN_G__)
		#include	"./std_map.hpp"
	#endif 	//	!defined(__LOLIX__TOY__STD_MAP__NICK__K_IN_G__)
namespace lolix{namespace toy{
	template<typename _Teh, typename _Key, typename _Tv, typename _Tc, typename _TAlc>
	archive<_Teh>& operator << (archive<_Teh>& arc, map<_Key, _Tv, _Tc, _TAlc> const& mp)
		{
		lx_u64 sv(mp.size());
		arc << sv;
		for ( typename map<_Key, _Tv, _Tc, _TAlc>::const_iterator iter = mp.begin(); iter != mp.end(); ++iter )
			arc << *iter;
		return arc;
		}
	template<typename _Teh, typename _Key, typename _Tv, typename _Tc, typename _TAlc>
	archive<_Teh>& operator >> (archive<_Teh>& arc, map<_Key, _Tv, _Tc, _TAlc>& mp)
		{
		lx_u64 sv;
		arc >> sv;
		mp.clear();
		typename map<_Key, _Tv, _Tc, _TAlc>::value_type v;
		auto rmv_v(arc.get_eh().push_destroy(&v));
		for ( size_type i = 0; i != (size_type)sv; ++i )
			{
			arc >> v;
			mp.insert(v);
			}
		return arc;
		}

}}

#endif	//	defined(LOLIX_DEF__ARC_SUPPORT_MAP) && !defined(__LOLIX_DEFIEND__ARC_SUPPORT_MAP__)



#if			defined(LOLIX_DEF__ARC_SUPPORT_STRING) && !defined(__LOLIX_DEFIEND__ARC_SUPPORT_STRING__)
	#define		__LOLIX_DEFIEND__ARC_SUPPORT_STRING__

	#if			!defined(__LOLIX__TOY__STD_STRING__NICK__K_IN_G__)
		#include	"./std_string.hpp"
	#endif	//	!defined(__LOLIX__TOY__STD_STRING__NICK__K_IN_G__)
namespace lolix{namespace toy{
	template<typename _Teh, typename _Ty, typename _CT, typename _Talc> LOLIX_INLINE_CALL
	archive<_Teh>&	operator << (archive<_Teh>& arc, basic_string<_Ty, _CT, _Talc> const& vec)
		{
		lx_u64 sv(vec.size());
		arc << sv;
		for ( size_type i = 0; i != vec.size(); ++i )
			arc << vec[i];
		return arc;
		}

	template<typename _Teh, typename _Ty, typename _CT, typename _Talc> LOLIX_INLINE_CALL
	archive<_Teh>&	operator >> (archive<_Teh>& arc, basic_string<_Ty, _CT, _Talc>& vec)
		{
		lx_u64 sv;
		arc >> sv;
		vec.resize((size_type)sv);
		for ( size_type i = 0; i != vec.size(); ++i )
			arc >> vec[i];
		return arc;
		}
}}
#endif	//	defined(LOLIX_DEF__ARC_SUPPORT_STRING) && !defined(__LOLIX_DEFIEND__ARC_SUPPORT_STRING__)


#if			defined(LOLIX_DEF__ARC_SUPPORT_VEC_MAP) && !defined(__LOLIX_DEFIEND__ARC_SUPPORT_VEC_MAP__)
	#define		__LOLIX_DEFIEND__ARC_SUPPORT_VEC_MAP__

	#if			!defined(__LOLIX__TOY__VEC_MAP__NICK__K_IN_G__)
		#include	"./vec_map.hpp"
	#endif	//	!defined(__LOLIX__TOY__VEC_MAP__NICK__K_IN_G__)
namespace lolix{namespace toy{
	template<typename _Teh, typename _TKey, typename _TMap, typename _TLess, typename _TAlc>
	archive<_Teh>& operator << (archive<_Teh>& arc, vec_multimap<_TKey, _TMap, _TLess, _TAlc> const& m)
		{
		arc << m.size();
		for ( typename vec_multimap<_TKey, _TMap, _TLess, _TAlc>::const_iterator iter = m.begin(), end = m.end()
			; iter != end
				; ++iter )
			{
			arc << iter->first << iter->second;
			}
		}
	template<typename _Teh, typename _TKey, typename _TMap, typename _TLess, typename _TAlc>
	archive<_Teh>& operator >> (archive<_Teh>& arc, vec_multimap<_TKey, _TMap, _TLess, _TAlc>& m)
		{
		size_type sz;
		arc >> sz;
		m.reserver(sz);
		for ( size_type i = 0; i != sz; ++i )
			{
			_TKey k;
			auto rmv_k(arc.get_eh().push_destroy(&k));
			_TMap m;
			auto rmv_m(arc.get_eh().push_destroy(&m));
			arc >> k >> m;
			m.insert(k, m);
			}
		}
	template<typename _Teh, typename _TKey, typename _TMap, typename _TLess, typename _TAlc>
	archive<_Teh>& operator << (archive<_Teh>& arc, vec_map<_TKey, _TMap, _TLess, _TAlc> const& m)
		{
		arc << m.size();
		for ( typename vec_map<_TKey, _TMap, _TLess, _TAlc>::const_iterator iter = m.begin(), end = m.end()
			; iter != end
				; ++iter )
			{
			arc << iter->first << iter->second;
			}
		return arc;
		}
	template<typename _Teh, typename _TKey, typename _TMap, typename _TLess, typename _TAlc>
	archive<_Teh>& operator >> (archive<_Teh>& arc, vec_map<_TKey, _TMap, _TLess, _TAlc>& m)
		{
		size_type sz;
		arc >> sz;
		m.reserve(sz);
		for ( size_type i = 0; i != sz; ++i )
			{
			_TKey k;
			_TMap v;
			auto rmv_k(arc.get_eh().push_destroy(&k));
			auto rmv_v(arc.get_eh().push_destroy(&v));
			arc >> k >> v;
			m.insert(k, v);
			}
		return arc;
		}
}}
#endif	//	defined(LOLIX_DEF__ARC_SUPPORT_VEC_MAP) && !defined(__LOLIX_DEFIEND__ARC_SUPPORT_VEC_MAP__)


#if			defined(LOLIX_DEF__ARC_SUPPORT_VEC_SET) && !defined(__LOLIX_DEFIEND__ARC_SUPPORT_VEC_SET__)
	#define		__LOLIX_DEFIEND__ARC_SUPPORT_VEC_SET__

	#if			!defined(__LOLIX__TOY__VEC_SET__NICK__K_IN_G__)
		#include	"./vec_set.hpp"
	#endif	//	!defined(__LOLIX__TOY__VEC_SET__NICK__K_IN_G__)
namespace lolix{namespace toy{
	template<typename _Teh, typename _TKey, typename _TLess, typename _TAlc>
	archive<_Teh>& operator << (archive<_Teh>& arc, vec_multiset<_TKey, _TLess, _TAlc> const& m)
		{
		arc << m.size();
		for ( typename vec_multiset<_TKey, _TLess, _TAlc>::const_iterator iter = m.begin(), end = m.end()
			; iter != end
				; ++iter )
			{
			arc << *iter;
			}
		}
	template<typename _Teh, typename _TKey, typename _TLess, typename _TAlc>
	archive<_Teh>& operator >> (archive<_Teh>& arc, vec_multiset<_TKey, _TLess, _TAlc>& m)
		{
		size_type sz;
		arc >> sz;
		m.reserver(sz);
		for ( size_type i = 0; i != sz; ++i )
			{
			_TKey k;
			auto rmv_k(arc.get_eh().push_destroy(&k));
			arc >> k;
			m.insert(k);
			}
		}
	template<typename _Teh, typename _TKey, typename _TLess, typename _TAlc>
	archive<_Teh>& operator << (archive<_Teh>& arc, vec_set<_TKey, _TLess, _TAlc> const& m)
		{
		arc << m.size();
		for ( typename vec_set<_TKey, _TLess, _TAlc>::const_iterator iter = m.begin(), end = m.end()
			; iter != end
				; ++iter )
			{
			arc << *iter;
			}
		return arc;
		}
	template<typename _Teh, typename _TKey, typename _TLess, typename _TAlc>
	archive<_Teh>& operator >> (archive<_Teh>& arc, vec_set<_TKey, _TLess, _TAlc>& m)
		{
		size_type sz;
		arc >> sz;
		m.reserve(sz);
		for ( size_type i = 0; i != sz; ++i )
			{
			_TKey k;
			auto rmv_k(arc.get_eh().push_destroy(&k));
			arc >> k;
			m.insert(k);
			}
		return arc;
		}
}}
#endif	//	defined(LOLIX_DEF__ARC_SUPPORT_VEC_SET) && !defined(__LOLIX_DEFIEND__ARC_SUPPORT_VEC_SET__)


#if			defined(LOLIX_DEF__ARC_SUPPORT_VECTOR) && !defined(__LOLIX_DEFIEND__ARC_SUPPORT_VECTOR__)
	#define		__LOLIX_DEFIEND__ARC_SUPPORT_VECTOR__

	#if			!defined(__LOLIX__TOY__STD_VECTOR__NICK__K_IN_G__)
		#include	"./std_vector.hpp"
	#endif	//	!defined(__LOLIX__TOY__STD_VECTOR__NICK__K_IN_G__)
namespace lolix{namespace toy{
	template<typename _Teh, typename _Ty, typename _Talc> LOLIX_INLINE_CALL
	archive<_Teh>&	operator << (archive<_Teh>& arc, vector<_Ty, _Talc> const& vec)
		{
		size_value sv(vec.size());
		arc << sv;
		for ( size_type i = 0; i != vec.size(); ++i )
			arc << vec[i];
		return arc;
		}

	template<typename _Teh, typename _Ty, typename _Talc> LOLIX_INLINE_CALL
	archive<_Teh>&	operator >> (archive<_Teh>& arc, vector<_Ty, _Talc>& vec)
		{
		size_value sv;
		arc >> sv;
		vec.resize((size_type)sv);
		for ( size_type i = 0; i != vec.size(); ++i )
			arc >> vec[i];
		return arc;
		}
}}
#endif	//	defined(LOLIX_DEF__ARC_SUPPORT_VECTOR) && !defined(__LOLIX_DEFIEND__ARC_SUPPORT_VECTOR__)

#undef		LOLIX_DEF__ARC_SUPPORT_BYTE_BUF
#undef		LOLIX_DEF__ARC_SUPPORT_KEY_BIND
#undef		LOLIX_DEF__ARC_SUPPORT_LIST
#undef		LOLIX_DEF__ARC_SUPPORT_MAP
#undef		LOLIX_DEF__ARC_SUPPORT_STRING
#undef		LOLIX_DEF__ARC_SUPPORT_VEC_MAP
#undef		LOLIX_DEF__ARC_SUPPORT_VEC_SET
